
--################# Set up main variables @Prefanatic
local NX = {}
local Quotes = {}

--#################  Main VGUI Controler @Prefanatic
function NX.DrawQuoteMAIN()

	local w = ScrW()
	local h = ScrH()
	local x = 200
	local y = 300
	
	local Refresh = false
	
	--################# Main Frame @Prefanatic
	local frame = CreateFrame( (w / 2) - (x / 2), (h / 2) - (y / 2), x, y, "Nodexian Quote Management", true, true, false, nil, frame )
		frame.Paint = function()
			surface.SetDrawColor( 0, 0, 0, 100 )
			surface.DrawRect( 0, 0, frame:GetWide(), frame:GetTall() )
		end
		
	--#################  Parental Panel @Prefanatic
	local panel = CreatePanel( 0, 20, frame:GetWide(), frame:GetTall(), Color( 0, 0, 0, 0 ), frame, panel )
	
	--################# Player Index section @Prefanatic
	local playerindex = CreateComboBox( 5, 5, 80, 100, panel, playerindex )
	
		--################# Player Index Refresher control @Prefanatic
		local function RefreshPlyIndex()
			playerindex:Clear()
			local files = file.Find("Nodexians/*.txt")
			for k,v in pairs(files) do
				local nick = string.Replace(v, ".txt", "")
				playerindex:AddItem( nick )
			end
		end
		RefreshPlyIndex()
		
	--################# Refresh All Controll @Prefanatic
	local function RefreshAll() Refresh = true RefreshPlyIndex() NX.LoadAll() end
		
	--################# Quote Entry Box @Prefanatic
	local quoteentry = CreateTextEntry( 90, 30, 100, 16, true, nil, panel, quoteentry )
		quoteentry:SetText("Type quote here")
		quoteentry.OnEnter = function() --################# Quote Entry Function Manager @Prefanatic
		
			if playerindex:GetSelectedItems() and playerindex:GetSelectedItems()[1] then -- If the player index is even valid
			
				local plynick = playerindex:GetSelectedItems()[1]:GetValue() -- Grab the nick
				local quote = quoteentry:GetValue() -- Grab the quote
				
				RunConsoleCommand( "nx_createquote", plynick, quote ) -- Run our console command
				
				quoteentry:SetText("Quote Set!") -- Style the quote
				timer.Simple(3, function() quoteentry:SetText("Type quote here") end)
				
				RefreshAll() -- Refresh
				
			end
		end
		
	--################# Add User Box @Prefanatic
	local quoteadduser = CreateTextEntry( 90, 10, 100, 16, true, nil, panel, quoteadduser )
		quoteadduser:SetText("Type a user to add!") -- Style
		quoteadduser.OnEnter = function() --################# Add User Function Manager @Prefanatic
		
			local plynick = quoteadduser:GetValue() -- grab the nick
		
			RunConsoleCommand( "nx_createquote", plynick, "nil") -- create the user
			
			quoteadduser:SetText("User Added!") -- style
			timer.Simple(3, function() quoteadduser:SetText("Type a user to add!") end)
			
			RefreshAll() -- refresh
			
		end
		
	--################# Quotes Label @Prefanatic
	local quoteslabel = CreateLabel( 5, 150, "Select a player to see quotes.", "default", panel, quoteslabel )
	
	--################# Quote Index @Prefanatic
	local quoteindex = CreateComboBox( 5, 110, 80, 160, panel, quoteindex )
		quoteindex:SetVisible(false)
	
	--################# Say Button OnClick @Prefanatic	
	local function OnClickFunc() if quoteindex:GetSelectedItems() and quoteindex:GetSelectedItems()[1] and playerindex:GetSelectedItems() and playerindex:GetSelectedItems()[1] then RunConsoleCommand("say", string.Cap(playerindex:GetSelectedItems()[1]:GetValue()) .. ": " .. quoteindex:GetSelectedItems()[1]:GetValue()) end end
	
	--################# Say button @Prefanatic	
	local sayqbutton = CreateButton( 110, 170, 70, 50, "Say it!", OnClickFunc, nil, nil, panel, sayqbutton )
		sayqbutton:SetVisible(false)
		
	--################# Refresh Button OnClick @Prefanatic
	local function OnClickFunc() RefreshAll() end 
	
	--################# Refresh Button @Prefanatic
	local refreshbutton = CreateButton( 90, 70, 45, 25, "Refresh", OnClickFunc, nil, nil, panel, refreshbutton )
	
	--################# Delete User Button OnClick @Prefanatic
	local function OnClickFunc() if playerindex:GetSelectedItems() and playerindex:GetSelectedItems()[1] then RunConsoleCommand("nx_removequotes", playerindex:GetSelectedItems()[1]:GetValue()) RefreshAll() end end
	
	--################# Delete User Button @Prefanatic
	local deleteuserbutton = CreateButton( 90, 50, 45, 25, "Delete", OnClickFunc, nil, nil, panel, deleteuserbutton )
	
	--################# Main Quote think @Prefanatic
	local function QuoteThink()
		
		if playerindex == nil then hook.Remove("Think", "QuotesThink") end -- If the index isnt valid, end
	
		if playerindex:GetSelectedItems() and playerindex:GetSelectedItems()[1] then -- if the index is valid
		
			local quotedata = "" -- I dont know.
			local nick = playerindex:GetSelectedItems()[1]:GetValue() -- Grab the nick
			
			if oldplyindex == nil then oldplyindex = nick end -- If the nick is  the same as before, dont do anything
			
			if oldplyindex != nick and Refresh == false then -- If the nick changed from the last update
				oldplyindex = nick -- set the new nick
				Refresh = true -- Call for a refresh
			end
			
			if Refresh then -- If we are refreshing
				--RefreshPlyIndex() -- Refresh the player index
			
				--local user = GetPlyFromNick( playerindex:GetSelectedItems()[1]:GetValue() )
				
				quoteindex:Clear() -- Clear old index
				
				NX.LoadAll() -- Load all users
				
				if !NX.CheckQuoteTable( nick ) then -- If the user has no quotes then tell the local player
					quoteslabel:SetText( "There are no quotes for this user" )
					quoteindex:SetVisible(false)
					quoteslabel:SetVisible(true)
					sayqbutton:SetVisible(false)
					Refresh = false
					return false
				end
				
				for k,v in pairs(Quotes[nick]) do -- For all the quotes he has, add them to quoteindex
					quoteindex:AddItem(v)
				end
				
				quoteindex:SetVisible(true)
				quoteslabel:SetVisible(false)
				sayqbutton:SetVisible(true)
				
				Refresh = false
				
			end
			
		end
		
	end
	hook.Add("Think", "QuotesThink", QuoteThink)
	
end
concommand.Add("nx_quotemanagement", NX.DrawQuoteMAIN)

--################# CreateQuote @Prefanatic
function NX.CreateQuote( ply, _, arg )

	local nick = arg[1] -- get nick
	local quote = arg[2] -- get quote
	
	--local user = GetPlyFromNick( nick ) -- not needed

	if nick == nil then printNX("You need to type in their name!") return false end -- If nick isnt anything, than end it
	
	if quote == nil then printNX("You need to quote their quote!") return false end -- If the quote isnt anything, then what the fuck.
	
	if quote == "nil" then -- If we are just adding the player, then create the file
	
		NX.Save( nick, {""} ) 
		NX.LoadAll()
		
	else
	
		printNX("Adding quote from " .. nick .. ": " .. quote) -- Add the quotessssss
		
		NX.Save( nick, {quote} )
		NX.LoadAll()
		
	end
	
end
concommand.Add("nx_createquote", NX.CreateQuote)

function NX.RemoveQuotes( ply, _, arg )

	local nick = arg[1]
	
	--local user = GetPlyFromNick( nick )
	
	if nick == nil then print("You need to type their name!") return false end
	
	printNX("Removing all quotes from " .. nick)
	
	NX.Delete( nick )
	
end
concommand.Add("nx_removequotes", NX.RemoveQuotes)
	
-- Table adding convience function
function NX.AddToQuotes( nick, quote )

	Quotes[nick] = quote
	
end

function NX.CheckQuoteTable( nick )

	if Quotes[nick] and Quotes[nick][1] != "" then return true else return false end

end

-- File loading and saving convinence functions.

function NX.FormatNick( nick )

	local nick = string.Replace(nick, ";", "")
	
	return nick 
	
end

function NX.Corrupt( data )

	if string.find(string.sub(data, 0, 1), ";") then
		
		printNX("Corruption data error in data " .. data)
	
		return true
	else
		return false
		
	end
	
end

function NX.Save( nick, content )

	local name = "Nodexians/" .. NX.FormatNick( nick ) .. ".txt"
	local content = string.Implode(";", content)
	
	local data = file.Read(name)
	
	if data and not NX.Corrupt( data ) then
		--printNX("Saving quotes from " .. name .. " with data " .. data .. " and adding content " .. tostring(content))
		file.Write(name, data .. ";" .. tostring(content))
	else
		file.Write(name, tostring(content))
	end
	
end

function NX.Load( nick )

	local name = "Nodexians/" .. NX.FormatNick( nick ) .. ".txt"
	local data = file.Read(name)
	
	local quote = string.Explode(";", data)
	
	--printNX("Loading quotes from " .. nick .. " with quotes " .. quote)
	NX.AddToQuotes( nick, quote )
	
end

function NX.LoadAll()
	
	local files = file.Find("Nodexians/*.txt")

	for k,v in pairs(files) do
		local nick = string.Replace(v, ".txt", "")
		local filename = "Nodexians/"..v
		local data = file.Read(filename)
		local quote = string.Explode(";", data)
		
		--printNX("Loading data from " .. nick .. " with data " .. data)
		
		NX.AddToQuotes( nick, quote )
		
	end
	
end

function NX.Delete( nick )

	local name = "Nodexians/" .. NX.FormatNick( nick ) .. ".txt"
	
	file.Delete(name)
	printNX("Deleted all data from " .. nick)
	
end

-- Prefantastic convience functions
function GetPlyFromNick( nick )

	local ply = 0

	for k,v in pairs(player.GetAll()) do
	
		if string.lower(v:Nick()) == string.lower(nick) then ply = v break end
		
	end
	
	return ply
	
end

function string.Cap( msg )

	local firstchar = string.sub(msg, 0, 1)
	local rest = string.sub(msg, 2 string.len(msg) - 2)
	local firstchar = string.upper(firstchar)
	local msg = firstchar .. rest
	
	return msg
	
end

function printNX( msg )

	print("{NODEXIANS} " .. msg)
	
end

function CreateLabel( posx, posy, text, font, parent, name )

	local name = vgui.Create("DLabel", parent)
		name:SetText( text )
		name:SetFont( font )
		name:SizeToContents()
		
		if posx == "center" then posx = (parent:GetWide() / 2) - (name:GetWide() / 2) end
		name:SetPos( posx, posy )
		name:SetVisible(true)
		
	return name
		
end

function CreatePanel( posx, posy, sizex, sizey, color, parent, name )

	if parent != nil then 
		name = vgui.Create("DPanel", parent)
	else
		name = vgui.Create("DPanel")
	end

		name:SetSize( sizex, sizey )
		name:SetPos( posx, posy )
		name.Paint = function()
			surface.SetDrawColor( color.r, color.g, color.b, color.a )
			surface.DrawRect( 0, 0, name:GetWide(), name:GetTall() )
		end
		
	return name
	
end

function CreateList( posx, posy, sizex, sizey, spacing, scrollbar, parent, name )

	if parent != nil then 
		name = vgui.Create("DPanelList", parent)
	else
		name = vgui.Create("DPanelList")
	end
	
	name:SetPos( posx, posy )
	name:SetSize( sizex, sizey)
	name:SetSpacing(spacing)
	name:EnableHorizontal(false)
	name:EnableVerticalScrollbar(scrollbar)
	
	return name
	
end

function CreateTextEntry( posx, posy, sizex, sizey, enter, onenter, parent, name )

	name = vgui.Create( "DTextEntry", parent )
	
	name:SetPos( posx, posy )
	name:SetSize( sizex, sizey )
	name:SetEnterAllowed( enter )
	
	name.OnEnter = onenter
	
	return name
	
end

function CreateFrame( posx, posy, sizex, sizey, title, draggable, showclose, blur, parent, name )

	if parent != nil then
		name = vgui.Create("DFrame")
	else
		name = vgui.Create("DFrame")
	end
	
		name:SetPos(posx, posy)
		name:SetSize(sizex, sizey)
		name:SetTitle(title)
		name:SetVisible(true)
		name:SetDraggable(draggable)
		name:ShowCloseButton(showclose)
		name:SetBackgroundBlur(blur)
		
		name:MakePopup()
		
	return name
	
end

function CreateComboBox( posx, posy, sizex, sizey, parent, name )

	if parent != nil then
		name = vgui.Create("DComboBox", parent)
	else
		name = vgui.Create("DComboBox")
	end
	
	name:SetPos( posx, posy )
	name:SetSize( sizex, sizey )
	name:SetMultiple( false )
	
	return name
	
end

function CreateButton( posx, posy, sizex, sizey, text, onclick, hoverenter, hoverexit, parent, name )

	if parent != nil then 
		name = vgui.Create("DButton", parent)
	else
		name = vgui.Create("DButton")
	end
	
		name:SetText( text )
		name:SetSize( sizex, sizey )
		if posx == "center" then posx = (parent:GetWide() / 2) - (name:GetWide() / 2) end
		name:SetPos( posx, posy )
		
		name.DoClick = onclick
		name.OnCursorEntered = hoverenter
		name.OnCursorExited = hoverexit
		
	return name
	
end